
/***************************************************************************
 *                                                                         *
 *     File:                ANTI-VIRUS                                     *
 *     Function:  This program demostrating file anti-virus managment      *
 *                                                                         *
 *     Author:            Long Yun Liang                                   *
 *     First edit:  1995,3,10                                              *
 *     Last  edit:  1996,11,5        All Rights Reserved                   *
 *                                                                         *
 *                                                                         *
 ***************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <io.h>
#include <fcntl.h>
#include <process.h>
#include <errno.h>
#include <mem.h>

#pragma pack(1)

/* defines for improved readability and less typing */

typedef unsigned char BYTE;
typedef unsigned WORD;
enum chioce { NO,YES };
enum FileType { COM,EXE };

/* stack size */

#define STACK_SIZE 9000
#define MEM_SIZE 8000
char far *stack_ptr;

/************************* public data *******************************/

typedef struct {
        WORD type;    /* 4D5A */
        WORD len_low;
        WORD len_high;  /* file length */
        WORD re_num;
        WORD head_len;  /* para */
        WORD min_size;
        WORD max_size;
        WORD init_ss;
        WORD init_sp;
        WORD add_sum;
        WORD init_ip;
        WORD init_cs;
        WORD re_ptr;
        WORD overlay_num;
        WORD no_use;
} EXE_HEAD;

EXE_HEAD *head;

WORD PSP;
WORD file_ss;
WORD file_sp;
WORD file_cs;
WORD file_ip;
WORD pspseg;
WORD re_seg;

long filesize;
int  filetype;
unsigned int num;
unsigned int low;
unsigned int ok=0;

/******  external routines that must be linked with this program *****/

void exebuild (char *);
void combuild (char *);
int  cutoff (char *,int);
int  overwrite (char *,int);
void helpmsg (void);
void message (void);
void memfile (int,int);
int  init (void(*)());
int  input (int);
int  init1 (int,int);
void prepost (unsigned,unsigned,unsigned,unsigned,unsigned,unsigned,unsigned,unsigned,unsigned,unsigned,unsigned,unsigned,unsigned,unsigned);
void getvec (void);
void setvec (void);

/************************* Main Program *******************************/

void main (int argc,char *argv[])
{

     char filename[128];
     char buffer[1024];
     FILE *fp;

     if (argc<=1)
        helpmsg();
     strcpy (filename,argv[1]);
     message ();
     printf ("Analyzing program  ....\n");
     if ((fp=fopen (filename,"rb"))==NULL)  {
        printf ("file not found .\naborting ...");
        return ;
     }
     fread (buffer,sizeof(char),0x20,fp);
     head=(EXE_HEAD *)(buffer);
     if (head->type==0x5a4d) filetype=EXE; else filetype=COM;
     fclose (fp);
     if (filetype==EXE) exebuild(filename); else combuild(filename);
     freemem (peek(PSP,0x2c));  /* free enverment */
     freemem (PSP);   /*  free memory */
}

void exebuild (char *fname)
{
     FILE *fp;
     FILE *fp1;
     FILE *fp2;
     char filename[128];
     int  headsize;
     int  error,count,i,ch,virus_len,last;
     char *mem,*head_buff,*pw;
     long entry_point,temp;
     unsigned cutsize;
     char buffer[1024];

     strcpy (filename,fname);
     fp=fopen (filename,"rb");
     fread (buffer,sizeof(char),0x20,fp);
     head=(EXE_HEAD *)(buffer);
     fseek(fp,0,SEEK_END);
     filesize=ftell(fp);
     filesize-=head->head_len*16;
     entry_point=head->init_cs*0x10+head->init_ip;
     cutsize=filesize-entry_point;
     num=filesize/0x10000;
     low=filesize-num*0x10000;
     fclose (fp);

     printf ("Remove virus of %u size .\n",cutsize);
     printf ("Continue anyway (Y/N)");
     if (cutsize>5000||cutsize<0)
        if (input(NO)==NO) return ;
     else
        if (input(YES)==NO) return ;
     getvec();
     /*  init C stack  */
     stack_ptr=malloc (STACK_SIZE);
     stack_ptr+=STACK_SIZE;
     error = init1(num,low);
     if (!error)  {
        printf ("Error %d installing Anti-Virus .\n",error);
        setvec();return ;
     }
     ok=0;
     error=spawnl(P_WAIT,filename,filename,NULL);
     setvec();
     if (!ok)  {
        printf ("Error running program %02X.\naborting ...",error);
        return ;
     }
     printf ("\n*********** PASS OK ***********\n");

     printf ("SOURCE file PSP segment: %04X\n",pspseg);
     printf ("SOURCE file CS:IP value: %04X:%04X\n",file_cs,file_ip);
     printf ("SOURCE file SS:SP value: %04X:%04X\n",file_ss,file_sp);
     re_seg=pspseg+0x10;
     file_cs-=re_seg;
     file_ss-=re_seg;
     file_ip-=2;

     printf ("Creat new EXE file ...\n");
     fp=fopen (filename,"rb+");
     fread (buffer,sizeof(char),0x20,fp);
     rewind (fp);
     head=(EXE_HEAD *)(buffer);
     head->init_ip=file_ip;
     head->init_cs=file_cs;
     head->init_sp=file_sp;
     head->init_ss=file_ss;
     fwrite (buffer,sizeof (char),0x20,fp);
     fclose (fp);
     printf ("Cut off virus of %u size ?",cutsize);
     if (input(NO)==YES) cutoff (filename,cutsize);
     else {
          printf ("Overwrite virus data ?");
          if (input(YES)==NO) return ;
          else overwrite(filename,cutsize);
     }
     printf("\nVirus clean successfully .");
}

void combuild (char *fname)
{
     FILE *fp;
     FILE *fp1;
     FILE *fp2;
     char filename[128];
     int  error,count;
     int  i,ch,fptr;
     unsigned cutsize;
     long ptr,temp;
     char *mem;
     unsigned *re_buff;
     char tempfile[128]="C:\\TEMPFILE.TMP";
     char buffer[64];
     char buffer1[64];

     strcpy (filename,fname);
     fp=fopen (filename,"rb");
     fseek(fp,0,SEEK_END);
     filesize=ftell(fp);

     printf ("Executeing program ...\n");

     getvec();
     /***********************  C Stack ***********************/
     stack_ptr=malloc (STACK_SIZE);
     stack_ptr+=STACK_SIZE;
     error = init(prepost);
     if (!error)  {
        printf ("Error %d installing Anti-Virus .\n",error);
        setvec();return ;
     }
     ok=0;
     error=spawnl(P_WAIT,filename,filename,NULL);
     setvec();
     if (!ok)  {
        printf ("Error running program %02X.\naborting ...",error);
        return ;
     }
     printf ("\n*********** PASS OK ***********\n");

     fp=fopen (filename,"rb+");
     fp1=fopen (tempfile,"rb");
     rewind(fp);rewind(fp1);
     fptr=filesize;
     while (!feof(fp1))  {
           fread (buffer,sizeof(char),10,fp);
           fread (buffer1,sizeof(char),10,fp1);
           if (memcmp(buffer,buffer1,10)==0)  {
              fptr=ftell (fp);
              break;
           }
     }
     rewind(fp);rewind(fp1);

     printf ("Write temprate file to %s of %u byte :",filename,fptr);
     if (input(YES)==NO)  {
        fclose (fp);fclose (fp1);return ;
     }
     i=0;
     while (!feof(fp1)&&i<fptr)  {
           ch=fgetc(fp1);
           fputc (ch,fp);
           i++;
     }
     fclose (fp);fclose(fp1);
     remove (tempfile);
     printf ("Do you known virus length ?");
     if (input(NO)==NO) return ;

     printf ("Input virus length :");
     scanf ("%d",&cutsize);
     cutoff (filename,cutsize);

     printf("Virus clean successfully .");
}

int  cutoff (char *filename,int cut_off_size)
{
     long new_len;
     int handle;
     char buffer[64];

     handle=open (filename,O_RDWR|O_BINARY);
     if (filetype==EXE)  {
        read (handle,buffer,0x20);
        head = (EXE_HEAD *)(buffer);
        filesize=head->len_high*512+head->len_low;
        filesize-=cut_off_size;
        head->len_high=filesize/512;
        head->len_low=filesize-head->len_high*512;
        lseek (handle,0,SEEK_SET);
        write (handle,buffer,0x20);
     }
     printf ("Original Size: %u  ",filelength(handle));
     new_len=filelength(handle)-cut_off_size;
     chsize (handle,new_len);
     printf ("Processed Size: %u  ",filelength(handle));
     close (handle);
     return 0;
}

int  overwrite (char *filename,int cut_off_size)
{
     int handle;
     char *buff;

     cut_off_size-=10;
     if ((buff=malloc (cut_off_size))==NULL) return 1;
     memset (buff,0xff,cut_off_size);
     handle=open (filename,O_RDWR|O_BINARY);
     filesize=filelength(handle);
     filesize-=cut_off_size;
     lseek (handle,filesize,SEEK_SET);
     write (handle,buff,cut_off_size);
     close (handle);
     free (buff);
     printf ("Overwrite %u byte of virus .",cut_off_size);
     return 0;
}

void helpmsg ()
{
     printf ("Power Anti-Virus V1.00 Copyright 1995 by Moonlight Studio. \n");
     printf ("Usage:       PAV  filename \n\n");
     printf ("Examples:    PAV  C:TEST.EXE\n");
     exit (1);
}

void message ()
{
     printf ("Moonlight Studio (R) Power Anit-Virus Utility (tm) Version 1.00\n");
     printf ("Copyright (C) 1994-95 . All rights reserved .\n\n");
}

int  input (int choice)
{
     int nokey,ch;

     if (choice==YES)  {
        printf (" Yes\b\b\b");nokey=YES;
        }
     else  {
        printf (" No \b\b\b");nokey=NO;
        }
     ch=toupper (getch());
     if (ch=='Y')  {
        printf ("Yes\n");return YES;
        }
     if (ch=='N')  {
        printf ("No \n");return NO;
        }

     printf ("\n");return nokey;
}

/*************** DOS Function Interrupt Serves Routine *********************/

void prepost (intnum,r_cs,r_ip,r_ss,r_sp,r_ax,r_bx,r_cx,r_dx,r_si,r_di,r_ds,r_es,r_bp)
     unsigned intnum,r_cs,r_ip,r_ss,r_sp,r_ax,r_bx,r_cx,r_dx,r_si,r_di,r_ds,r_es,r_bp;
{
     unsigned temp;
     unsigned char fun;
     unsigned char r_dh,r_dl,r_ch,r_cl;
     fun=r_ax>>8;

     if (!ok)  {
     switch (intnum)  {
               case 0x21 :
                    if (fun==0x00||fun==0x4c||fun==0x31) {
                       ok=1;
                       pspseg=r_cs;
                       memfile(0,filesize);
                       }
                    break;

               case 0x20 :
               case 0x27 :
                       ok=1;
                       pspseg=r_cs;
                       memfile(0,filesize);
                       break;

               default : break;
               }
        }
}


/***************************************************************************
 *      End of file ----- MAIN.C                                           *
 *      Copyright (c) Moonlight Studio .  1996,11,5                        *
 ***************************************************************************/
